package top.hcode.hoj.service;

import cn.hutool.core.lang.Validator;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.nutz.lang.Strings;
import org.springframework.stereotype.Component;
import top.hcode.hoj.common.LazyDao;
import top.hcode.hoj.dao.org.OrgDao;
import top.hcode.hoj.pojo.entity.org.Org;
import top.hcode.hoj.shiro.AccountProfile;
import top.hcode.hoj.utils.ShiroUtils;
import top.hcode.hoj.utils.SqlUtil;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author orangej
 * @since 2025/1/23
 */
@Component
@RequiredArgsConstructor
public class UserAuthService {

    private final OrgDao orgDao;
    private final LazyDao dao;

    public boolean isLogin() {
        return ShiroUtils.getUid() != null;
    }

    /**
     * 检查当前登陆用户是否有权限访问指定org节点
     * 先根据 school_has_user 查到所有用户的所有学校，然后判断 orgId 是否是这些学校的子节点
     *
     * @param orgId 节点id
     */
    public void checkOrgId(String orgId) {
        if (Strings.isBlank(orgId)) {
            return;
        }

        AccountProfile accountProfile = ShiroUtils.getProfile();
        if (accountProfile == null) {
            throw new IllegalArgumentException("用户未登录");
        }

        if ("root".equals(accountProfile.getUsername())) {
            return;
        }

        // query school of user
        String uid = ShiroUtils.getUid();


        // 指定的org
        Org org = orgDao.getById(orgId);
        Validator.validateNotNull(org, "org不存在 : {}", orgId);

        // org 是否为 school
        if (org.getOrgType() == 2) {
            if (dao.fetchInt("select count(1) from org_has_user where user_id = ? and org_id = ?", uid, orgId) == 0) {
                throw new IllegalArgumentException(String.format("您无权访问 %s %s", org.getId(), org.getOrgName()));
            }
        }

        // org 是否为school 的下级
        List<Org> campusOfUser = orgDao.queryCampusOfUser(uid);
        if (campusOfUser.isEmpty()) {
            throw new IllegalArgumentException("用户不属于任何学校");
        }
        if (campusOfUser.stream().anyMatch(campus -> org.getTreeCode().startsWith(campus.getTreeCode()))) {
            return;
        }

        throw new IllegalArgumentException(String.format("您无权访问 %s %s", org.getId(), org.getOrgName()));
    }

    /**
     * 获取当前用户id
     * @return 用户id
     */
    public String uid() {
        return ShiroUtils.getUid();
    }

    /**
     * 获取当前用户
     * @return 当前用户
     */
    public String username() {
        return ShiroUtils.getProfile().getUsername();
    }

    /**
     * 检查当前用户是否是root用户
     * @return 是否是root用户
     */
    public boolean isRoot() {
        Subject subject = SecurityUtils.getSubject();
        return subject.hasRole("root");
    }

    /**
     * 获取当前用户所属学校的id列表
     * @return 学校id列表
     */
    public List<String> getSchoolIdList() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.hasRole("root")) {
            return orgDao.queryAllSchool().stream().map(Org::getId).collect(Collectors.toList());
        }

        // 从 org_has_user 表中获取当前用户的 org 节点，然后根据 tree_code 获取学校id
        return dao.queryString(SqlUtil.sql("select id from org where tree_code in " +
                        "(select distinct substr(tree_code,1,4) from org_has_user where user_id = ?) order by tree_code"),
                ShiroUtils.getUid());
    }
}
